package com.sys.basics.utils.quartz;

import com.alibaba.fastjson.JSON;
import com.sys.basics.config.constant.ScheduleConstant;
import com.sys.basics.entity.SysScheduleJob;
import com.sys.basics.entity.SysScheduleJobLog;
import com.sys.basics.service.SysScheduleJobLogService;
import com.sys.basics.utils.ApplicationContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.concurrent.*;


/**
 * 定时任务
 */
@Component
@Slf4j
@DisallowConcurrentExecution
public class ScheduleJobUtils extends QuartzJobBean {

    @Autowired
    private SysScheduleJobLogService sysScheduleJobLogService;

    private ExecutorService service = new ThreadPoolExecutor(10, 50, 0L,
            TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        String jsonJob = jobExecutionContext.getMergedJobDataMap().getString(ScheduleConstant.JOB_PARAM_KEY);
        SysScheduleJob scheduleJob = JSON.parseObject(jsonJob, SysScheduleJob.class);


        //数据库保存执行日志
        SysScheduleJobLog scheduleJobLog = new SysScheduleJobLog();
        scheduleJobLog.setJobId(scheduleJob.getId());
        scheduleJobLog.setJobName(scheduleJob.getTaskName());
        scheduleJobLog.setRemark(scheduleJob.getRemark());
        scheduleJobLog.setJobCode(scheduleJob.getTaskCode());
        scheduleJobLog.setBeanName(scheduleJob.getBeanName());
        scheduleJobLog.setParams(scheduleJob.getParams());
        scheduleJobLog.setGmtCreate(LocalDateTime.now());

        //任务开始时间
        long startTime = System.currentTimeMillis();

        try {
            //执行任务
            log.info("任务准备执行，任务ID:{}", scheduleJob.getId());
            ScheduleRunnableUtils task = new ScheduleRunnableUtils(scheduleJob.getBeanName(), scheduleJob.getParams());
            Future<?> future = service.submit(task);
            future.get();

            //任务执行总时长
            long times = System.currentTimeMillis() - startTime;
            scheduleJobLog.setTimes((int) times);
            scheduleJobLog.setStatus(ScheduleConstant.ExecuteResult.SUCCESS.getStatus());
            log.info("任务执行成功，任务ID:{}, 总共耗时: {}毫秒", scheduleJob.getId(), times);

        } catch (Exception e) {
            log.error("任务执行失败，任务ID:{}, 错误信息: {}", scheduleJob.getId(), e);

            //任务执行总时长
            long times = System.currentTimeMillis() - startTime;
            scheduleJobLog.setTimes((int) times);
            scheduleJobLog.setStatus(ScheduleConstant.ExecuteResult.FAILED.getStatus());
            scheduleJobLog.setError("任务执行失败: 具体请查看日志!");
        } finally {
            if (sysScheduleJobLogService == null) {
                sysScheduleJobLogService = ApplicationContextUtils.getBean(SysScheduleJobLogService.class);
            }
//            sysScheduleJobLogService.recordLog(scheduleJobLog);
        }
    }
}
